#include <iostream>
#include <sw/redis++/redis++.h>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include "util.hpp"


//get 和 set 的使用
void test1(sw::redis::Redis& redis)
{
    std::cout << "get 和 set 命令的使用 " << std::endl;

    //清空一下数据库, 避免之前残留的数据有干扰
    redis.flushall();

    //使用set设置key
    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");
    redis.set("key4", "444");

    //使用get获取value
    auto value1 = redis.get("key1");
    //optional 可以隐式转成 bool类型, 可以直接在if中判定, 如果是无效元素, 就是返回false
    if(value1)
    {
        std::cout << "value1: " << value1.value() << std::endl;
    }
    auto value2 = redis.get("key2");
    if (value2)
    {
        std::cout << "value2: " << value2.value() << std::endl;
    }
    auto value3 = redis.get("key3");
    if (value3)
    {
        
        std::cout << "value3: " << value3.value() << std::endl;
    }
    auto value4 = redis.get("key3");
    if (value4)
    {
        std::cout << "value3: " << value4.value() << std::endl;
    }
    auto value5 = redis.get("key5");
    if (value5)
    {
        std::cout << "value5: " << value5.value() << std::endl;
    }
}

//使用exists命令
void test2(sw::redis::Redis& redis)
{
    std::cout << "exists 命令的使用 " << std::endl;
    //清空数据库,避免之前的数据干扰本次操作
    redis.flushall();

    redis.set("key1", "111");
    auto ret = redis.exists("key1");
    std::cout << ret << std::endl;

    auto ret1 = redis.exists("key2");
    std::cout << ret1 << std::endl;

    //一次判断多个key
    auto ret2 = redis.exists({"key1", "key2", "key3"});
    std::cout << ret2 << std::endl;
}

//使用del命令
void test3(sw::redis::Redis &redis)
{
    std::cout << "del 命令的使用 " << std::endl;

    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");

    std::cout << redis.del("key1") << std::endl;

    //一次删除多个key
    std::cout << redis.del({"key1", "key2"}) << std::endl;

}

void test4(sw::redis::Redis& redis)
{
    std::cout << "keys 命令的使用" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("ke2", "222");
    redis.set("key3", "333");

    // keys的第二个参数, 是一个"插入迭代器", 咋们需要先准备好一个保存结果的容器,
    // 接下来再创建一个插入迭代器指向容器的位置, 就可以把keys获取到的结果依次通过插入迭代器插入到容器指定的位置中了;
    std::vector<std::string> result;
    auto it = std::back_inserter(result);
    redis.keys("*", it);
    printContainer(result);
}

void test5(sw::redis::Redis& redis)
{
    using namespace std::chrono_literals;

    std::cout << "expire 和 ttl 命令的使用" << std::endl;
    redis.flushall();

    redis.set("key", "111");

    // 10s 就等价于 std::chrono::second(10)
    redis.expire("key", 10s);

    std::this_thread::sleep_for(3s);//休眠3s

    std::cout << redis.ttl("key") << std::endl;

}

void test6(sw::redis::Redis& redis)
{
    std::cout << "type 命令的使用" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    std::cout << redis.type("key1") << std::endl;

    redis.lpush("key2", "222");
    std::cout << redis.type("key2") << std::endl;

    redis.hset("key3", "aaa", "222");
    redis.hset("key7", std::make_pair("bbb", "333"));
    std::cout << redis.type("key3") << std::endl;

    redis.sadd("key4", "1234");
    std::cout << redis.type("key4") << std::endl;

    redis.zadd("key5", "吕布", 99);
    std::cout << redis.type("key5") << std::endl;
}

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    test6(redis);
    return 0;
}


